<?php
/**
 * 数据权限控制服务
 * 实现多维度数据权限控制：个人权限、部门权限、共享权限、审批权限
 */

declare(strict_types=1);

namespace app\service;

use think\facade\Db;
use think\facade\Cache;
use app\common\DataPermissionHelper;

class DataPermissionService
{
    /**
     * 权限类型常量
     */
    public const PERMISSION_TYPES = [
        'PERSONAL' => 'personal',        // 个人数据权限
        'DEPARTMENT' => 'department',    // 部门数据权限  
        'SHARED' => 'shared',           // 共享数据权限
        'APPROVAL' => 'approval',       // 审批权限
        'LEADER' => 'leader'            // 领导权限
    ];

    /**
     * 数据权限字段映射
     */
    public const FIELD_MAPPING = [
        'belong_uid' => '归属用户ID',
        'belong_did' => '归属部门ID', 
        'admin_id' => '创建用户ID',
        'did' => '部门ID',
        'share_ids' => '共享用户ID列表',
        'check_uids' => '审批人ID列表',
        'check_history_uids' => '历史审批人ID列表'
    ];

    /**
     * 获取用户数据权限信息
     * @param int $userId 用户ID
     * @param string $module 模块名称
     * @return array
     */
    public function getUserDataPermissions(int $userId, string $module = ''): array
    {
        $permissions = [];
        
        // 使用DataPermissionHelper获取权限信息
        $userPermissions = DataPermissionHelper::getCurrentUserPermissions();
        if (!$userPermissions && $userId > 0) {
            // 如果无法从中间件获取权限信息，直接查询用户信息
            $userInfo = $this->getUserPermissionInfo($userId);
        } else {
            $userInfo = $userPermissions;
        }
        
        // 构建权限信息
        $permissions[] = [
            'module' => $module ?: 'all',
            'dimension' => 'personal',
            'value' => $userId,
            'description' => '个人数据权限'
        ];
        
        if (!empty($userInfo['department_id'])) {
            $permissions[] = [
                'module' => $module ?: 'all',
                'dimension' => 'department', 
                'value' => $userInfo['department_id'],
                'description' => '部门数据权限'
            ];
        }
        
        if (!empty($userInfo['leader_departments'])) {
            $permissions[] = [
                'module' => $module ?: 'all',
                'dimension' => 'leader',
                'value' => implode(',', $userInfo['leader_departments']),
                'description' => '领导数据权限 - 可管理' . count($userInfo['leader_departments']) . '个部门'
            ];
        }
        
        // 添加审批权限信息
        $approvalTypes = $this->getUserApprovalTypes($userId);
        if (!empty($approvalTypes)) {
            $permissions[] = [
                'module' => $module ?: 'all',
                'dimension' => 'approval',
                'value' => implode(',', $approvalTypes),
                'description' => '审批权限 - 支持' . count($approvalTypes) . '种审批类型'
            ];
        }
        
        // 添加共享数据统计
        $sharedDataCount = $this->getUserSharedDataCount($userId, $module);
        if ($sharedDataCount > 0) {
            $permissions[] = [
                'module' => $module ?: 'all',
                'dimension' => 'shared',
                'value' => $sharedDataCount,
                'description' => '共享数据权限 - 可访问' . $sharedDataCount . '条共享数据'
            ];
        }
        
        return $permissions;
    }
    
    /**
     * 获取模块权限配置
     * @param string $module 模块名称
     * @return array
     */
    public function getModulePermissionConfig(string $module = ''): array
    {
        $config = [
            'customer' => [
                'name' => '客户管理',
                'dimensions' => [
                    'personal' => '个人数据',
                    'department' => '部门数据',
                    'shared' => '共享数据'
                ]
            ],
            'contract' => [
                'name' => '合同管理',
                'dimensions' => [
                    'personal' => '个人合同',
                    'department' => '部门合同',
                    'shared' => '共享合同',
                    'approval' => '审批权限'
                ]
            ],
            'expense' => [
                'name' => '报销管理',
                'dimensions' => [
                    'personal' => '个人报销',
                    'department' => '部门报销',
                    'approval' => '审批权限'
                ]
            ],
            'invoice' => [
                'name' => '发票管理',
                'dimensions' => [
                    'personal' => '个人发票',
                    'department' => '部门发票',
                    'approval' => '审批权限'
                ]
            ],

        ];
        
        if (empty($module)) {
            return $config;
        }
        
        return $config[$module] ?? [];
    }
    
    /**
     * 构建数据权限查询条件
     * @param int $userId 用户ID
     * @param string $module 模块名称
     * @param array $options 额外选项
     * @return array 查询条件数组
     */
    public function buildPermissionConditions(int $userId, string $module, array $options = []): array
    {
        if ($userId <= 0) {
            throw new \Exception('用户ID不能为空');
        }

        // 超级管理员拥有所有权限
        if ($userId === 1) {
            return []; // 空条件表示无限制
        }
        
        // 使用DataPermissionHelper构建综合权限条件
        $baseWhere = [];
        
        // 根据模块和选项设置权限类型
        $permissionOptions = [
            'personal' => true,     // 个人数据权限
            'department' => true,   // 部门数据权限
            'shared' => true,       // 共享数据权限
            'approval' => true      // 审批数据权限
        ];
        
        // 根据模块调整权限类型
        if ($module === 'expense' || $module === 'invoice') {
            // 财务模块主要使用个人和审批权限
            $permissionOptions['shared'] = false;
        } elseif ($module === 'customer') {
            // 客户管理主要使用个人、部门和共享权限
            $permissionOptions['approval'] = false;
        }
        
        // 合并用户自定义选项
        $permissionOptions = array_merge($permissionOptions, $options);
        
        // 使用DataPermissionHelper构建条件
        $where = DataPermissionHelper::buildComprehensiveDataWhere($baseWhere, $permissionOptions);
        
        return $where;
    }
    
    /**
     * 检查用户对特定数据的访问权限
     * @param int $userId 用户ID
     * @param string $module 模块名称
     * @param int $dataId 数据ID
     * @param array $options 权限选项
     * @return bool
     */
    public function checkDataAccess(int $userId, string $module, int $dataId, array $options = []): bool
    {
        if ($userId <= 0 || $dataId <= 0) {
            return false;
        }
        
        // 超级管理员拥有所有权限
        if ($userId === 1) {
            return true;
        }
        
        // 获取模块对应的数据表名
        $tableName = $this->getTableNameByModule($module);
        if (empty($tableName)) {
            return false;
        }
        
        // 这里应该实现具体的权限检查逻辑
        // 暂时返回 true，后续需要完善实现
        return true;
    }
    
    /**
     * 根据模块名获取数据表名
     * @param string $module
     * @return string
     */
    private function getTableNameByModule(string $module): string
    {
        $tableMapping = [
            'customer' => 'customer',
            'contract' => 'contract',
            'expense' => 'expense',
            'invoice' => 'invoice',
            'project' => 'project',
            'lawcase' => 'lawcase',
            'oa_plan' => 'oa_plan',
            'oa_schedule' => 'oa_schedule',
            'oa_work' => 'oa_work',
            'finance_payment' => 'finance_payment',
            'finance_ticket' => 'finance_ticket',
            'adm_car' => 'adm_car',
            'adm_meeting' => 'adm_meeting',
            'adm_seal' => 'adm_seal',
            'adm_official' => 'adm_official',
        ];
        
        return $tableMapping[$module] ?? $module;
    }
    
    /**
     * 应用数据权限到查询对象
     * @param \think\db\Query $query 查询对象
     * @param int $userId 用户ID
     * @param string $module 模块名称
     * @return \think\db\Query
     */
    public function applyPermissionToQuery($query, int $userId, string $module)
    {
        if ($userId <= 0) {
            throw new \Exception('用户ID不能为空');
        }
        
        // 超级管理员拥有所有权限
        if ($userId === 1) {
            return $query;
        }
        
        // 构建权限条件
        $conditions = $this->buildPermissionConditions($userId, $module);
        
        // 应用权限条件到查询对象
        if (!empty($conditions)) {
            foreach ($conditions as $condition) {
                if (is_array($condition) && count($condition) >= 2) {
                    // 标准条件 ['字段', '操作符', '值']
                    if (count($condition) >= 3) {
                        $query->where($condition[0], $condition[1], $condition[2]);
                    } else {
                        // 简单条件 ['字段', '值']
                        $query->where($condition[0], $condition[1]);
                    }
                } elseif (is_string($condition)) {
                    // 字符串条件
                    $query->where($condition);
                }
            }
        }
        
        return $query;
    }
    
    /**
     * 获取用户权限信息
     * @param int $userId
     * @return array
     */
    private function getUserPermissionInfo(int $userId): array
    {
        if ($userId <= 0) {
            return [];
        }
        
        try {
            $cacheKey = 'user_permission_info_' . $userId;
            $userInfo = Cache::get($cacheKey);
            
            if ($userInfo === null) {
                // 获取用户基本信息
                $user = Db::name('admin')->where('id', $userId)->find();
                if (!$user) {
                    return [];
                }
                
                // 获取部门信息
                $department = null;
                if ($user['did'] > 0) {
                    $department = Db::name('department')->where('id', $user['did'])->find();
                }
                
                // 获取用户作为领导的部门
                $leaderDepts = Db::name('department')
                    ->where('leader_id', $userId)
                    ->column('id');
                
                $userInfo = [
                    'id' => $user['id'],
                    'username' => $user['username'],
                    'name' => $user['name'],
                    'did' => $user['did'],
                    'department_id' => $user['did'], // 为了兼容DataPermissionHelper
                    'position_id' => $user['position_id'],
                    'status' => $user['status'],
                    'department' => $department,
                    'leader_departments' => array_map('intval', $leaderDepts ?: []),
                    'is_super_admin' => $user['id'] == 1
                ];
                
                // 缓存用户权限信息，缓存时间30分钟
                Cache::set($cacheKey, $userInfo, 1800);
            }
            
            return $userInfo;
        } catch (\Exception $e) {
            return [];
        }
    }
    
    /**
     * 获取用户审批类型
     * @param int $userId
     * @return array
     */
    private function getUserApprovalTypes(int $userId): array
    {
        // 这里可以根据用户角色和权限返回审批类型
        // 简化实现，后续可以扩展
        return [
            'expense',
            'invoice',
            'contract'
        ];
    }
    
    /**
     * 获取用户共享数据数量
     * @param int $userId
     * @param string $module
     * @return int
     */
    private function getUserSharedDataCount(int $userId, string $module = ''): int
    {
        try {
            $tableName = $this->getTableNameByModule($module);
            if (empty($tableName) || empty($module)) {
                return 0;
            }
            
            $count = Db::name($tableName)
                ->where('', 'exp', Db::raw("FIND_IN_SET('{$userId}', share_ids)"))
                ->count();
                
            return (int)$count;
        } catch (\Exception $e) {
            return 0;
        }
    }
    
    /**
     * 更新数据共享权限
     * @param string $module 模块名称
     * @param int $dataId 数据ID
     * @param array $shareUserIds 共享用户ID列表
     * @param int $operatorId 操作人ID
     * @return array
     */
    public function updateSharePermission(string $module, int $dataId, array $shareUserIds, int $operatorId): array
    {
        $tableName = $this->getTableNameByModule($module);
        if (empty($tableName)) {
            throw new \Exception('无效的模块名称');
        }
        
        try {
            // 检查数据是否存在
            $data = Db::name($tableName)->where('id', $dataId)->find();
            if (!$data) {
                throw new \Exception('数据不存在');
            }
            
            // 处理共享用户ID列表
            $shareIds = '';
            if (!empty($shareUserIds) && is_array($shareUserIds)) {
                // 去重并过滤无效值
                $validUserIds = array_filter(array_unique($shareUserIds), function($id) {
                    return is_numeric($id) && $id > 0;
                });
                $shareIds = implode(',', $validUserIds);
            }
            
            // 更新数据
            $updateData = [
                'share_ids' => $shareIds,
                'update_time' => time()
            ];
            
            $result = Db::name($tableName)->where('id', $dataId)->update($updateData);
            
            return [
                'success' => $result !== false,
                'data_id' => $dataId,
                'share_user_count' => count($validUserIds ?? []),
                'share_ids' => $shareIds
            ];
        } catch (\Exception $e) {
            throw new \Exception('更新共享权限失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 获取部门数据权限统计
     * @param int $userId
     * @return array
     */
    public function getDepartmentStats(int $userId): array
    {
        $userInfo = $this->getUserPermissionInfo($userId);
        if (empty($userInfo)) {
            return [];
        }
        
        $stats = [
            'user_info' => [
                'id' => $userInfo['id'],
                'name' => $userInfo['name'],
                'department_id' => $userInfo['department_id'],
                'department_name' => $userInfo['department']['name'] ?? ''
            ],
            'permissions' => [
                'own_department' => $userInfo['department_id'] ?? 0,
                'leader_departments' => $userInfo['leader_departments'] ?? [],
                'leader_department_count' => count($userInfo['leader_departments'] ?? []),
                'is_super_admin' => $userInfo['is_super_admin'] ?? false
            ],
            'data_counts' => []
        ];
        
        // 统计各模块的数据数量
        $modules = ['customer', 'contract', 'expense', 'invoice'];
        foreach ($modules as $module) {
            try {
                $tableName = $this->getTableNameByModule($module);
                
                // 个人数据数量
                $personalCount = Db::name($tableName)
                    ->where('belong_uid', $userId)
                    ->count();
                
                // 部门数据数量
                $departmentCount = 0;
                if ($userInfo['department_id'] > 0) {
                    $departmentCount = Db::name($tableName)
                        ->where('belong_did', $userInfo['department_id'])
                        ->count();
                }
                
                // 共享数据数量
                $sharedCount = Db::name($tableName)
                    ->where('', 'exp', Db::raw("FIND_IN_SET('{$userId}', share_ids)"))
                    ->count();
                
                $stats['data_counts'][$module] = [
                    'personal' => (int)$personalCount,
                    'department' => (int)$departmentCount,
                    'shared' => (int)$sharedCount,
                    'total' => (int)($personalCount + $departmentCount + $sharedCount)
                ];
            } catch (\Exception $e) {
                $stats['data_counts'][$module] = [
                    'personal' => 0,
                    'department' => 0,
                    'shared' => 0,
                    'total' => 0
                ];
            }
        }
        
        return $stats;
    }
    
    /**
     * 获取可共享的用户列表
     * @param int $userId 当前用户ID
     * @param string $keyword 搜索关键词
     * @param int $departmentId 部门ID
     * @return array
     */
    public function getShareableUsers(int $userId, string $keyword = '', int $departmentId = 0): array
    {
        try {
            $where = [];
            $where[] = ['id', '<>', $userId]; // 排除自己
            $where[] = ['status', '=', 1]; // 只显示正常用户
            
            // 关键词搜索
            if (!empty($keyword)) {
                $where[] = ['name|username|mobile', 'like', '%' . trim($keyword) . '%'];
            }
            
            // 部门筛选
            if ($departmentId > 0) {
                $where[] = ['did', '=', $departmentId];
            }
            
            $users = Db::name('admin')
                ->alias('a')
                ->join('department d', 'a.did = d.id', 'LEFT')
                ->join('position p', 'a.position_id = p.id', 'LEFT')
                ->field('a.id, a.name, a.username, a.mobile, a.did, d.name as department_name, p.name as position_name')
                ->where($where)
                ->order('a.did asc, a.id asc')
                ->limit(50) // 限制返回数量
                ->select()
                ->toArray();
            
            return $users;
        } catch (\Exception $e) {
            return [];
        }
    }
    
    /**
     * 清除用户权限缓存
     * @param int $userId
     */
    public function clearUserPermissionCache(int $userId)
    {
        $cacheKey = 'user_permission_info_' . $userId;
        Cache::delete($cacheKey);
    }
}
